home *** CD-ROM | disk | FTP | other *** search
- /*
- * @(#)variables.c 1.8 6/18/88
- */
- #include "assert.h"
- #include "genutils.h"
- #include "nodes.h"
- #include "builtins.h"
- #include "regdefs.h"
- #include "emit.h"
- #include "environment.h"
- #include "MyParser.h"
- #include "flags.h"
- #include "trace.h"
- #include "system.h"
- #include "semantics.h"
-
- void squirrelStringLiteral(), dumpStringLiterals();
- void squirrelVectorLiteral(), dumpVectorLiterals();
-
- /*
- * This file defines the variable stack. It is used to keep track of
- * partial results in the code-generation process.
- *
- * When code is being generated for an invocation, the target will be on top
- * of the stack, and the parameters will be there in normal order, that is,
- * the last parameter will be on top of the stack.
- */
-
- #define MAXVARIABLESTACKDEPTH 100
- Variable vStack[MAXVARIABLESTACKDEPTH];
- VariablePtr vStackTop = &vStack[-1];
-
- extern NodePtr currentObject;
-
- Boolean vEmpty()
- {
- return(vStackTop == &vStack[-1]);
- }
-
- void vPushDD(data, abcon)
- DD data, abcon;
- {
- assert(vStackTop < &vStack[MAXVARIABLESTACKDEPTH]);
- ++vStackTop;
- vStackTop->data = data;
- vStackTop->abCon = abcon;
- }
-
- void vPush(v)
- Variable v;
- {
- assert(vStackTop < &vStack[MAXVARIABLESTACKDEPTH]);
- *++vStackTop = v;
- }
-
- Boolean isPop(d)
- DD d;
- {
- return(d.kind == DD_Address && d.value.address.autoIncrement);
- }
-
- Boolean isSameDD(val, var)
- DD val, var;
- {
- return(val.kind == var.kind && val.value.id == var.value.id ||
- (val.kind == DD_Address && var.kind == DD_Address &&
- val.value.address.base == var.value.address.base &&
- val.value.address.hasIndex == var.value.address.hasIndex &&
- (!val.value.address.hasIndex ||
- val.value.address.indexReg == var.value.address.indexReg) &&
- val.value.address.offset == var.value.address.offset &&
- !val.value.address.autoIncrement &&
- !val.value.address.autoDecrement &&
- !var.value.address.autoIncrement &&
- !var.value.address.autoDecrement) ||
- (val.kind == DD_Address && var.kind == DD_Address &&
- val.value.address.base == var.value.address.base &&
- !val.value.address.hasIndex && !var.value.address.hasIndex &&
- val.value.address.offset == 0 && var.value.address.offset == 0 &&
- val.value.address.autoIncrement &&
- var.value.address.autoDecrement));
- }
-
- Boolean isNextAddress(data, abCon)
- DD data, abCon;
- {
- if (data.kind != DD_Address || abCon.kind != DD_Address) return(FALSE);
- if (data.value.address.autoIncrement && abCon.value.address.autoIncrement ||
- data.value.address.autoDecrement && abCon.value.address.autoDecrement)
- return(TRUE);
- return((data .value.address.base == Register &&
- abCon.value.address.base == Register &&
- abCon.value.address.offset == data .value.address.offset+1) ||
- (data .value.address.base == abCon.value.address.base &&
- abCon.value.address.offset == data .value.address.offset+4));
- }
-
- DD nextAddress(d)
- DD d;
- {
- DD result;
- result = d;
- if (result.value.address.autoIncrement||result.value.address.autoDecrement)
- return (result);
- if (d.value.address.base == Register) {
- assert(result.value.address.offset <= 15); /* TODO this should be last
- allocatable register - 1 */
- result.value.address.offset ++;
- } else {
- result.value.address.offset += 4;
- result.value.address.baseIsTemporary = FALSE;
- result.value.address.indexIsTemporary = FALSE;
- }
- return(result);
- }
-
- void vPushValue(p, c)
- NodePtr p;
- Context c;
- {
- Variable result;
- result.data = nullDD;
- result.abCon = nullDD;
- switch (p->tag) {
- case P_BUILTINLIT:
- vPushValue(refToBuiltinFromToken(B_IT, p->b.builtinlit.whichType), c);
- break;
- case P_NILLIT:
- result.data = nilDD;
- result.abCon = nilDD;
- vPush(result);
- break;
- case P_CHARLIT:
- result.data.kind = DD_Manifest;
- result.data.value.manifest = (int)p->b.charlit.string[0];
- result.abCon = buildConCon(CHARACTERINDEX);
- vPush(result);
- break;
- case P_BOOLLIT:
- result.data.kind = DD_Manifest;
- result.data.value.manifest = p->b.boollit.value;
- result.abCon = buildConCon(BOOLEANINDEX);
- vPush(result);
- break;
- case P_REALLIT:
- result.data.kind = DD_RealManifest;
- result.data.value.realmanifest = p->b.reallit.string;
- result.abCon = buildConCon(REALINDEX);
- vPush(result);
- break;
- case P_INTLIT:
- result.data.kind = DD_Manifest;
- result.data.value.manifest = atoi(p->b.intlit.string);
- result.abCon = buildConCon(INTEGERINDEX);
- vPush(result);
- break;
- case P_STRINGLIT:
- result.data.kind = DD_Label;
- result.data.value.label = nextLabelNumber++;
- result.abCon = buildConCon(STRINGINDEX);
- squirrelStringLiteral(result.data.value.label, p->b.stringlit.string);
- vPush(result);
- break;
- case P_GLOBALREF:
- resolveGlobal(p, (ValuePtr) NULL);
- vPushValue(p->b.globalref.value, c);
- break;
- case P_ATLIT:
- /*
- * When we find an atlit as the value of some symbol, it is a reference
- * to a particular object that was created at compile time.
- */
- result.abCon = buildConCon(SIGNATUREINDEX);
- result.data.kind = DD_OIDToCodePtr;
- result.data.value.id = p->b.atlit.id;
- ensureGenerate(p->b.atlit.id);
- vPush(result);
- break;
- case P_OBLIT:
- /*
- * When we find an oblit as the value of some symbol, it is either a
- * reference to a particular object that was created at compile time,
- * or a reference to self.
- */
- if (p == currentObject) {
- result.abCon = buildAbConFromObject(p);
- result.data.kind = DD_Self;
- } else {
- result.abCon = buildAbConFromObject(p);
- assert(p->b.oblit.id != 0);
- result.data.kind = DD_OIDToODP;
- result.data.value.id = p->b.oblit.id;
- }
- vPush(result);
- break;
- default:
- assert(FALSE);
- }
- }
-
- void vPushOwnName(q)
- NodePtr q;
- {
- NodePtr itsName;
- assert(q->tag == P_OBLIT);
- itsName = Construct(P_STRINGLIT, 0);
- itsName->b.stringlit.string = ST_SymbolName(q->b.oblit.name->b.symdef.symbol);
- vPushValue(itsName, anyContext);
- FreeNode(itsName);
- }
-
- void vPushOwnType(q)
- NodePtr q;
- {
- assert(q->tag == P_OBLIT);
- assert(q->b.oblit.myat != NN);
- vPushValue(q->b.oblit.myat, anyContext);
- }
-
- void vPushVariable(st)
- Symbol st;
- {
- Variable v;
- NodePtr ct;
-
- /*
- * Push the address of the thing.
- */
- v.data.kind = DD_Address;
- v.data.value.address = st->v.address;
-
- if (st->value.CTinfo != NULL) {
- v.abCon = buildAbCon(getID(st->value.ATinfo),getCodeID(st->value.CTinfo));
- } else {
- ct = resolveToCTOrAT(st->value.ATinfo);
- if (ct->tag == P_OBLIT) {
- v.abCon = buildAbCon(getID(st->value.ATinfo), getCodeOID(ct));
- } else {
- v.abCon = nextAddress(v.data);
- setDDAbstractType(v.abCon, getID(st->value.ATinfo));
- }
- }
- assert(vStackTop < &vStack[MAXVARIABLESTACKDEPTH]);
- *++vStackTop = v;
- }
-
- Boolean hasARealValue(st)
- register Symbol st;
- {
- register NodePtr ob;
- if (st->isSelf) {
- assert(st->value.value != NN);
- return(TRUE);
- } else if (st->value.value == NN) {
- return (FALSE);
- } else {
- ob = st->value.value;
- if (ob->tag == P_GLOBALREF) {
- return(TRUE);
- } else if (ob->tag == P_ATLIT || ob->tag == P_OBLIT) {
- if (ob->b.oblit.f.writeSeparately) {
- assert(ob->b.atlit.id != 0);
- return(TRUE);
- } else {
- return(FALSE);
- }
- } else {
- assert(FALSE);
- /*NOTREACHED*/
- }
- }
- }
-
- DD vGetSymbolAbCon(st, data)
- Symbol st;
- DD data;
- {
- DD abcon;
- NodePtr ct;
- if (st->value.CTinfo != NULL) {
- abcon = buildAbCon(getID(st->value.ATinfo), getCodeID(st->value.CTinfo));
- } else {
- ct = resolveToCTOrAT(st->value.ATinfo);
- if (ct->tag == P_OBLIT) {
- abcon = buildAbCon(getID(st->value.ATinfo), getCodeOID(ct));
- } else {
- abcon = nextAddress(data);
- setDDAbstractType(abcon, getID(st->value.ATinfo));
- }
- }
- return(abcon);
- }
-
- void vPushSymbol(st, c)
- Symbol st;
- Context c;
- {
- Variable v;
-
- /*
- * What this does is look at the value field of the reference and do the
- * right thing. If the value is known then that value is used at compile
- * time, which implies that the concrete type must be known as well. If it
- * is not known, then if the concrete type is known we push a Variable with
- * the Ab/Con set to a manifest and the value to the address of the
- * symbol, otherwise both the value and the Ab/Con are addresses.
- */
- if (hasARealValue(st)) {
- vPushValue(st->value.value, c);
- } else {
- v.data.kind = DD_Address;
- v.data.value.address = st->v.address;
- v.abCon = vGetSymbolAbCon(st, v.data);
- assert(vStackTop < &vStack[MAXVARIABLESTACKDEPTH]);
- *++vStackTop = v;
- }
- }
-
- void vSwap()
- {
- Variable v;
- assert(vStackTop >= &vStack[1]);
- v = *vStackTop;
- *vStackTop = *(vStackTop - 1);
- *(vStackTop - 1) = v;
- }
-
- Variable vPop()
- {
- assert(vStackTop >= &vStack[0]);
- return(*vStackTop--);
- }
-
- void vDiscard()
- {
- assert(vStackTop >= &vStack[0]);
- freeDD(vStackTop->data);
- freeDD(vStackTop->abCon);
- vStackTop --;
- }
-
- /*
- * Discard the dd n from the top. To discard the top one use vDiscardN(0);
- */
- void vDiscardN(n)
- int n;
- {
- register int i;
- assert(vStackTop >= &vStack[n]);
- freeDD((vStackTop - n)->data);
- freeDD((vStackTop - n)->abCon);
- for (i = n; i > 0; i--) {
- *(vStackTop - i) = *(vStackTop - i + 1);
- }
- vStackTop --;
- }
-
- /*
- * Peek at the dd n from the top. To get the top one use vPeek(0);
- */
- Variable *vPeek(n)
- int n;
- {
- assert(vStackTop >= &vStack[n]);
- return(vStackTop - (n));
- }
-
- Variable vTop()
- {
- assert(vStackTop >= &vStack[0]);
- return(*vStackTop);
- }
-
- DD vPopData()
- {
- assert(vStackTop >= &vStack[0]);
- return((*vStackTop--).data);
- }
-
- DD vPopAbCon()
- {
- assert(vStackTop >= &vStack[0]);
- return((*vStackTop--).abCon);
- }
-
- DD vTopData()
- {
- assert(vStackTop >= &vStack[0]);
- return((*vStackTop).data);
- }
-
- DD vTopAbCon()
- {
- assert(vStackTop >= &vStack[0]);
- return((*vStackTop).abCon);
- }
-
- void ddGenerateAssign(vardata, varabcon, valdata, valabcon)
- DD vardata, varabcon, valdata, valabcon;
- {
- Boolean doFunnyAbCon = FALSE;
- IFTRACE(assign, 1) {
- fprintf(stdout, "ddGenerateAssign:\n");
- fprintf(stdout, "vardata == "); displayDD(stdout, vardata, '\n');
- fprintf(stdout, "varabcon == "); displayDD(stdout, varabcon, '\n');
- fprintf(stdout, "valdata == "); displayDD(stdout, valdata, '\n');
- fprintf(stdout, "valabcon == "); displayDD(stdout, valabcon, '\n');
- fprintf(stdout, "==> ");
- }
- if (isSameDD(valdata, vardata) && isSameDD(valabcon, varabcon)) {
- IFTRACE(assign, 1) {
- fprintf(stdout, "nothing\n");
- }
- return;
- }
- if (valabcon.kind == DD_AbCon && getDDAbstractType(varabcon) != (OID)0xff000000)
- setDDAbstractType(valabcon, getDDAbstractType(varabcon));
-
- if (vardata.kind == DD_Address && varabcon.kind == DD_Address) {
- doFunnyAbCon = valabcon.kind == DD_Address &&
- getDDAbstractType(valabcon) != getDDAbstractType(varabcon);
- if (doFunnyAbCon) {
- if (vardata.value.address.autoDecrement) {
- assert(varabcon.value.address.autoDecrement);
- doFunnyAbCon = FALSE;
- }
- }
-
- assert(isNextAddress(vardata, varabcon));
- if (valdata.kind == DD_Manifest && valabcon.kind == DD_Manifest) {
- /*
- * This is a case for a funny movq.
- */
- #ifdef vax
- if (valdata.value.manifest == 0 && valabcon.value.manifest == 0) {
- emit("\tclrq\t");
- writeDD(vardata, '\n');
- IFTRACE(assign, 1) {
- fprintf(stdout, "\tclrq\t");
- displayDD(stdout, vardata, '\n');
- }
- } else {
- emit("\tmovq\t$0x%08x%08x,",
- valdata.value.manifest, valabcon.value.manifest);
- writeDD(vardata, '\n');
- IFTRACE(assign, 1) {
- fprintf(stdout, "\tmovq\t$0x%08x%08x,",
- valdata.value.manifest, valabcon.value.manifest);
- displayDD(stdout, vardata, '\n');
- }
- }
- #endif
- #ifdef sun
- emitMove(valdata, vardata, 'l');
- emitMove(valabcon, varabcon, 'l');
- IFTRACE(assign, 1) {
- fprintf(stdout, "\tmovl\t$0x%08x,", valdata.value.manifest);
- displayDD(stdout, vardata, '\n');
- fprintf(stdout, "\tmovl\t$0x%08x,", valabcon.value.manifest);
- displayDD(stdout, varabcon, '\n');
- }
- #endif
- } else if (valdata.kind == DD_Address && valabcon.kind == DD_Address &&
- isNextAddress(valdata, valabcon)) {
- if (valabcon.value.address.autoIncrement) {
- NodePtr ct;
- DD newabcon;
- ct = getBestInfoFromAbCon(valabcon);
- if (getDDAbstractType(varabcon) == (OID) 0xff000000 ||
- getDDAbstractType(valabcon) == (OID) 0xff000000) {
- /* no sweat, we are cheating for some reason */
- #ifdef vax
- emitMove(valdata, vardata, 'q');
- #endif
- #ifdef sun
- emitMove(valdata, vardata, 'l');
- emitMove(valabcon, varabcon, 'l');
- #endif
- } else if (ct->tag == P_OBLIT) {
- /* no sweat, we know the concrete type */
- newabcon = buildAbConFromObject(ct);
- if (getDDAbstractType(newabcon) != getDDAbstractType(varabcon)) {
- /* we know the concrete type, but we expect a different one */
- emitMove(valdata, vardata, 'l');
- emit(POPABCON);
- TRACE0(assign, 1, POPABCON);
- newabcon = buildAbCon(getDDAbstractType(varabcon), getDDConcreteType(newabcon));
- emitMove(newabcon, varabcon, 'l');
- } else {
- #ifdef vax
- emitMove(valdata, vardata, 'q');
- #endif
- #ifdef sun
- emitMove(valdata, vardata, 'l');
- emitMove(valabcon, varabcon, 'l');
- #endif
- }
- } else {
- /* we always need to do them here */
- emitMove(valdata, vardata, 'l');
- fixDDView(valabcon, varabcon, getDDAbstractType(varabcon), FALSE);
- }
- } else if (doFunnyAbCon) {
- emitMove(valdata, vardata, 'l');
- fixDDView(valabcon, varabcon, getDDAbstractType(varabcon), TRUE);
- } else {
- #ifdef vax
- emitMove(valdata, vardata, 'q');
- #endif
- #ifdef sun
- if (vardata.value.address.autoDecrement) {
- emitMove(valabcon, varabcon, 'l');
- emitMove(valdata, vardata, 'l');
- } else {
- emitMove(valdata, vardata, 'l');
- emitMove(valabcon, varabcon, 'l');
- }
- #endif
- }
- } else if (vardata.value.address.autoDecrement) {
- /* push, so we have to do the abCon first */
- assert(!doFunnyAbCon);
- assert(varabcon.value.address.autoDecrement);
- if (valdata.kind == DD_PSLCondition) {
- /* we need to put the value from the PSL into somewhere */
- Variable v;
- v.data = valdata;
- v.abCon = valabcon;
- vForceToTemp(&v, TS_PSL);
- valdata = v.data;
- valabcon = v.abCon;
- }
- emitMove(valabcon, varabcon, 'l');
- emitMove(valdata, vardata, 'l');
- } else {
- /* pop or dont care, so we do the data first */
- assert(!doFunnyAbCon);
- if (valdata.kind == DD_Address && valdata.value.address.autoIncrement)
- assert(FALSE);
- emitMove(valdata, vardata, 'l');
- emitMove(valabcon, varabcon, 'l');
- }
- } else {
- /* just the data */
- assert(vardata.kind == DD_Address);
- assert(varabcon.kind == DD_AbCon || varabcon.kind == DD_Manifest);
- emitMove(valdata, vardata, 'l');
- if (isPop(valabcon)) {
- emit(POPABCON);
- TRACE0(assign, 1, POPABCON);
- }
- }
- freeDD(valdata);
- freeDD(valabcon);
- }
-
- void ddGenerateMovqAssign(size, vardata, varabcon, valdata, valabcon)
- int size;
- DD vardata, varabcon, valdata, valabcon;
- {
- if (size == 8 && valabcon.kind == DD_AbCon) {
- /* we need to worry since we need to do a movq */
- Variable auxv, *aux = &auxv;
- aux->data = pusher;
- aux->abCon = pusher;
- setDDAbstractType(aux->abCon, getDDAbstractType(valabcon));
- ddGenerateAssign(aux->data, aux->abCon, valdata, valabcon);
- aux->data = popper;
- aux->abCon = popper;
- ddGenerateAssign(vardata, varabcon, aux->data, aux->abCon);
- } else {
- ddGenerateAssign(vardata, varabcon, valdata, valabcon);
- }
- }
-
- void vGenerateAssign()
- {
- register VariablePtr var, val;
-
- assert(vStackTop >= &vStack[1]);
- val = vStackTop;
- var = (vStackTop - 1);
- ddGenerateAssign(var->data, var->abCon, val->data, val->abCon);
- (void) vPop();
- (void) vPop();
- }
-
- void findTemp(v, size, brand)
- Variable *v;
- int size;
- Brand brand;
- {
- int registerNo, stackAddress;
- registerNo = allocateReg(size / 4, brand);
- if (registerNo >= 0) {
- v->data = buildRegisterDD(registerNo);
- } else {
- stackAddress = TS_Allocate(size, brand);
- v->data.kind = DD_Address;
- v->data.value.address = nullAddress;
- v->data.value.address.base = regs_l;
- v->data.value.address.baseIsTemporary = TRUE;
- v->data.value.address.offset = stackAddress;
- }
- if (size == 8) v->abCon = nextAddress(v->data);
- }
-
- void vForceToTemp(v, which)
- register Variable *v;
- int which;
- {
- int registerNo, stackAddress;
- DD newdata, newabcon;
- NodePtr ct;
-
- if (! (((which & TS_Stack) &&
- v->data.kind == DD_Address &&
- v->data.value.address.base == regs_sp &&
- v->data.value.address.autoIncrement) ||
- ((which & TS_PSL) &&
- v->data.kind == DD_PSLCondition) ||
- ((which & TS_Self) && v->data.kind == DD_Self) ||
- ((which & TS_Label) &&
- v->data.kind == DD_Label))) return;
-
- newabcon = v->abCon;
- if (newabcon.kind != DD_AbCon) {
- ct = resolveOIDToCTOrAT(getDDAbstractType(newabcon));
- if (ct->tag == P_OBLIT) {
- newabcon = buildAbCon(getDDAbstractType(newabcon), ct->b.oblit.codeOID);
- }
- }
- if (newabcon.kind == DD_AbCon) {
- registerNo = allocateReg(1, abConToBrand(newabcon));
- if (registerNo >= 0) {
- newdata = buildRegisterDD(registerNo);
- } else {
- stackAddress = TS_Allocate(4, abConToBrand(newabcon));
- newdata.kind = DD_Address;
- newdata.value.address = nullAddress;
- newdata.value.address.base = regs_l;
- newdata.value.address.baseIsTemporary = TRUE;
- newdata.value.address.offset = stackAddress;
- }
- ddGenerateAssign(newdata, newabcon, v->data, v->abCon);
- v->data = newdata;
- v->abCon = newabcon;
- } else {
- /* check for thing on stack, if so, put it on stack */
- if (v->abCon.value.address.autoIncrement) {
- registerNo = -1;
- } else {
- registerNo = allocateReg(2, VariableBrand);
- }
- if (registerNo >= 0) {
- newdata = buildRegisterDD(registerNo);
- } else {
- stackAddress = TS_Allocate(8, VariableBrand);
- newdata.kind = DD_Address;
- newdata.value.address = nullAddress;
- newdata.value.address.base = regs_l;
- newdata.value.address.baseIsTemporary = TRUE;
- newdata.value.address.offset = stackAddress;
- }
- newabcon = nextAddress(newdata);
- setDDAbstractType(newabcon, getDDAbstractType(v->abCon));
- ddGenerateAssign(newdata, newabcon, v->data, v->abCon);
- v->data = newdata;
- v->abCon = newabcon;
- }
- }
-
- typedef struct {
- int regNo;
- DD argument;
- } KARec, *KARecPtr;
-
- /*
- * This one preempts all the kernel registers, assigns the given things to
- * the given input registers, and claims the result register with the given
- * brand.
- */
-
- /*VARARGS2*/
- DD preemptAndAssign(resultBrand, nArgs, firstArg)
- Brand resultBrand;
- int nArgs;
- KARec firstArg;
- {
- KARecPtr args = &firstArg;
- int i;
- Boolean done[4];
- DD d;
- done[0] = done[1] = done[2] = done[3] = FALSE;
- d.kind = DD_Address;
- d.value.address = nullAddress;
- d.value.address.base = Register;
-
- for (i = 0; i < nArgs; i++) {
- d.value.address.offset = args[i].regNo;
- if (isSameDD(args[i].argument, d)) {
- done[args[i].regNo] = TRUE;
- }
- }
- for (i = 0; i < 4; i++) {
- if (!done[i]) preemptReg(i, 1);
- }
- for (i = 0; i < nArgs; i++) {
- if (!done[args[i].regNo]) {
- claimReg(args[i].regNo, 1, DataBrand);
- emitMove(args[i].argument, buildRegisterDD(args[i].regNo), 'l');
- }
- }
- for (i = 0; i < nArgs; i++) {
- freeReg(args[i].regNo, 1);
- }
- claimReg(regs_arg1, 1, resultBrand);
- return(buildRegisterDD(regs_arg1));
- }
-
- void vDisplayStack()
- {
- register VariablePtr v;
- for (v = vStackTop; v >= &vStack[0]; v--) {
- fprintf(stdout, "Variable stack [%d]\n data -> ", v - &vStack[0]);
- displayDD(stdout, v->data, '\n');
- fprintf(stdout, " abCon-> ");
- displayDD(stdout, v->abCon, '\n');
- }
- fflush(stdout);
- }
-
- typedef struct sStringLiteral {
- int label;
- char *string;
- struct sStringLiteral *next;
- } StringLiteral, *SLPtr;
- static SLPtr slHead = NULL;
-
- typedef struct sVectorLiteral {
- int label;
- int elementTypeSize;
- OID vecCodeOID;
- NodePtr vector;
- struct sVectorLiteral *next;
- } VectorLiteral, *VLPtr;
- static VLPtr vlHead = NULL;
-
- void squirrelStringLiteral(label, string)
- int label;
- char *string;
- {
- register SLPtr s;
- s = (SLPtr) malloc(sizeof(StringLiteral));
- s->next = slHead;
- s->label = label;
- s->string = string;
- slHead = s;
- }
-
- void dumpStringLiterals()
- {
- register SLPtr s;
- while (slHead != NULL) {
- s = slHead;
- slHead = s->next;
- emitStringObject(s->string, s->label, (char *)NULL, 0);
- free((char *) s);
- }
- }
-
- void squirrelVectorLiteral(label, vector, elementTypeSize, vecCodeOID)
- int label;
- NodePtr vector;
- int elementTypeSize;
- OID vecCodeOID;
- {
- register VLPtr s;
- s = (VLPtr) malloc(sizeof(VectorLiteral));
- s->next = vlHead;
- s->label = label;
- s->elementTypeSize = elementTypeSize;
- s->vecCodeOID = vecCodeOID;
- s->vector = vector;
- vlHead = s;
- }
- void dumpVectorLiterals()
- {
- register VLPtr s;
- while (vlHead != NULL) {
- s = vlHead;
- vlHead = s->next;
- emitVectorObject(s->vector, s->label, s->elementTypeSize, s->vecCodeOID);
- free((char *) s);
- }
- }
-